using Domain.Examin;
using Domain.User;
using Infratructure.Interface;
using MediatR;
using MES.Server.API.Application.Command.ApprovalProcess;
using Microsoft.EntityFrameworkCore;
using ReturnValue;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MES.Server.API.Application.Handler.ApprovalProcess
{
    public class GetApprovalFlowDesignHandler : IRequestHandler<GetApprovalFlowDesignQuery, ApiResult<FlowDesignDTO>>
    {
        private readonly IRepository<ApprovalNodeModel> nodeRepo;
        private readonly IRepository<approvalProcessInstanceModel> processInstanceRepo;
        private readonly IRepository<ApprovalProcessModel> processModelRepo;
        private readonly IRepository<ApprovalAssigneeModel> assigneeRepo;
        private readonly IRepository<AccountModel> accountRepo;
        private readonly IRepository<RoleModel> roleRepo;
        private readonly IRepository<DepartmentModel> departmentRepo;

        public GetApprovalFlowDesignHandler(
            IRepository<ApprovalNodeModel> nodeRepo,
            IRepository<approvalProcessInstanceModel> processInstanceRepo,
            IRepository<ApprovalProcessModel> processModelRepo,
            IRepository<ApprovalAssigneeModel> assigneeRepo,
            IRepository<AccountModel> accountRepo,
            IRepository<RoleModel> roleRepo,
            IRepository<DepartmentModel> departmentRepo)
        {
            this.nodeRepo = nodeRepo;
            this.processInstanceRepo = processInstanceRepo;
            this.processModelRepo = processModelRepo;
            this.assigneeRepo = assigneeRepo;
            this.accountRepo = accountRepo;
            this.roleRepo = roleRepo;
            this.departmentRepo = departmentRepo;
        }

        public async Task<ApiResult<FlowDesignDTO>> Handle(GetApprovalFlowDesignQuery request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<FlowDesignDTO>
            {
                Data = new FlowDesignDTO()
            };

            try
            {
                // 1. 查找流程实例
                var processInstance = await processInstanceRepo.GetAll()
                    .Where(p => p.productionOrder == request.BusinessId && !p.IsDel)
                    .FirstOrDefaultAsync();

                if (processInstance == null)
                {
                    // 没有找到流程实例，创建一个默认的流程设计
                    result.Data = CreateDefaultFlowDesign();
                    result.Code = StatusCode.Success;
                    result.Message = "返回默认流程设计";
                    return result;
                }

                // 2. 获取流程定义
                var processModel = await processModelRepo.GetValue(processInstance.processId);
                if (processModel == null)
                {
                    result.Code = StatusCode.Fail;
                    result.Message = "未找到流程定义";
                    return result;
                }

                // 设置基本流程信息
                result.Data.ProcessId = processModel.Id;
                result.Data.ProcessName = processModel.processName;
                result.Data.Description = processModel.description;

                // 3. 获取所有节点
                var nodes = await nodeRepo.GetAll()
                    .Where(n => n.processId == processModel.Id && !n.IsDel)
                    .ToListAsync();

                if (nodes == null || !nodes.Any())
                {
                    // 没有找到节点，返回默认设计
                    result.Data = CreateDefaultFlowDesign();
                    result.Code = StatusCode.Success;
                    result.Message = "返回默认流程设计";
                    return result;
                }

                // 4. 构建节点和边
                int xPosition = 200; // 起始X坐标
                int yPosition = 200; // 起始Y坐标
                Dictionary<long, string> nodeIdMapping = new Dictionary<long, string>(); // 数据库ID到前端ID的映射

                foreach (var node in nodes)
                {
                    // 为每个节点生成一个前端ID
                    string frontendNodeId = $"node_{node.Id}";
                    nodeIdMapping[node.Id] = frontendNodeId;

                    // 获取节点的审批人信息
                    var assignee = await assigneeRepo.GetAll()
                        .Where(a => a.nodeId == node.Id && !a.IsDel)
                        .FirstOrDefaultAsync();

                    // 创建节点DTO
                    var nodeDto = new NodeDTO
                    {
                        Id = frontendNodeId,
                        Type = GetNodeType(node.nodeType),
                        Text = node.nodeName,
                        X = xPosition,
                        Y = yPosition,
                        Properties = new NodeProperties
                        {
                            NodeDescription = node.nodeDescription,
                            TimeLimit = node.timeLimit ?? 24
                        }
                    };

                    // 如果存在审批人，添加审批人信息
                    if (assignee != null)
                    {
                        nodeDto.Properties.ApproverRoleId = assignee.roleId;
                        nodeDto.Properties.ApproverUserId = assignee.userId;
                        nodeDto.Properties.DepartmentId = assignee.departmentId;

                        // 查找审批人名称信息
                        if (assignee.userId.HasValue)
                        {
                            var user = await accountRepo.GetValue(assignee.userId.Value);
                            if (user != null)
                            {
                                nodeDto.Properties.ApproverUserName = user.AccountName;
                            }
                        }

                        if (assignee.roleId.HasValue)
                        {
                            var role = await roleRepo.GetValue(assignee.roleId.Value);
                            if (role != null)
                            {
                                nodeDto.Properties.ApproverRoleName = role.RoleName;
                            }
                        }

                        if (assignee.departmentId.HasValue)
                        {
                            var department = await departmentRepo.GetValue(assignee.departmentId.Value);
                            if (department != null)
                            {
                                nodeDto.Properties.DepartmentName = department.DepartmentName;
                            }
                        }
                    }

                    result.Data.Nodes.Add(nodeDto);
                    
                    // 更新下一个节点的位置（简单的从左到右排列）
                    xPosition += 250;
                }

                // 5. 创建节点之间的连接
                int edgeIndex = 1;
                foreach (var node in nodes)
                {
                    // 如果有下一个节点，创建连接
                    if (node.nextnodeId.HasValue && node.nextnodeId.Value > 0)
                    {
                        if (nodeIdMapping.ContainsKey(node.Id) && nodeIdMapping.ContainsKey(node.nextnodeId.Value))
                        {
                            var edge = new EdgeDTO
                            {
                                Id = $"edge_{edgeIndex++}",
                                SourceNodeId = nodeIdMapping[node.Id],
                                TargetNodeId = nodeIdMapping[node.nextnodeId.Value],
                                Text = ""
                            };
                            result.Data.Edges.Add(edge);
                        }
                    }
                }

                result.Code = StatusCode.Success;
                result.Message = "获取流程设计成功";
                return result;
            }
            catch (Exception ex)
            {
                result.Code = StatusCode.Fail;
                result.Message = $"获取流程设计失败：{ex.Message}";
                return result;
            }
        }

        /// <summary>
        /// 创建默认的流程设计
        /// </summary>
        private FlowDesignDTO CreateDefaultFlowDesign()
        {
            var defaultDesign = new FlowDesignDTO
            {
                ProcessId = 1,
                ProcessName = "采购审批流程",
                Description = "默认审批流程",
                Nodes = new List<NodeDTO>
                {
                    new NodeDTO
                    {
                        Id = "node_1",
                        Type = "circle",
                        Text = "开始",
                        X = 200,
                        Y = 200
                    },
                    new NodeDTO
                    {
                        Id = "node_2",
                        Type = "rect",
                        Text = "人事审批",
                        X = 400,
                        Y = 200,
                        Properties = new NodeProperties
                        {
                            NodeDescription = "需要人事审批",
                            TimeLimit = 24,
                            ApproverRoleName = "人事"
                        }
                    },
                    new NodeDTO
                    {
                        Id = "node_3",
                        Type = "rect",
                        Text = "财务审批",
                        X = 600,
                        Y = 200,
                        Properties = new NodeProperties
                        {
                            NodeDescription = "需要财务审批",
                            TimeLimit = 24,
                            ApproverRoleName = "财务"
                        }
                    },
                    new NodeDTO
                    {
                        Id = "node_4",
                        Type = "rect",
                        Text = "董事长审批",
                        X = 800,
                        Y = 200,
                        Properties = new NodeProperties
                        {
                            NodeDescription = "需要董事长审批",
                            TimeLimit = 24,
                            ApproverRoleName = "董事长"
                        }
                    },
                    new NodeDTO
                    {
                        Id = "node_5",
                        Type = "circle",
                        Text = "结束",
                        X = 1000,
                        Y = 200
                    }
                },
                Edges = new List<EdgeDTO>
                {
                    new EdgeDTO
                    {
                        Id = "edge_1",
                        SourceNodeId = "node_1",
                        TargetNodeId = "node_2",
                        Text = ""
                    },
                    new EdgeDTO
                    {
                        Id = "edge_2",
                        SourceNodeId = "node_2",
                        TargetNodeId = "node_3",
                        Text = ""
                    },
                    new EdgeDTO
                    {
                        Id = "edge_3",
                        SourceNodeId = "node_3",
                        TargetNodeId = "node_4",
                        Text = ""
                    },
                    new EdgeDTO
                    {
                        Id = "edge_4",
                        SourceNodeId = "node_4",
                        TargetNodeId = "node_5",
                        Text = ""
                    }
                }
            };

            return defaultDesign;
        }

        /// <summary>
        /// 根据节点类型获取前端节点类型
        /// </summary>
        private string GetNodeType(int nodeType)
        {
            switch (nodeType)
            {
                case 1: // 开始节点
                    return "circle";
                case 3: // 结束节点
                    return "circle";
                case 2: // 审批节点
                default:
                    return "rect";
            }
        }
    }
}
